package com.drugmanage.service.impl;

import com.drugmanage.Base.BaseService;
import com.drugmanage.constant.DmConstant;
import com.drugmanage.dao.PermissionDao;
import com.drugmanage.dao.RoleDao;
import com.drugmanage.dao.UserDao;
import com.drugmanage.dao.UserRoleDao;
import com.drugmanage.entity.User;
import com.drugmanage.entity.UserRole;
import com.drugmanage.exception.ParamsExcetion;
import com.drugmanage.model.UserModel;
import com.drugmanage.query.UserQuery;
import com.drugmanage.service.IUserService;
import com.drugmanage.utils.AssertUtil;
import com.drugmanage.utils.Md5Util;
import com.drugmanage.utils.ValidateUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import javafx.beans.binding.ObjectExpression;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

@Service
public class UserService extends BaseService<User> implements IUserService {

    @Resource
    private UserDao userDao;
    @Resource
    private UserRoleDao userRoleDao;
    @Resource
    private PermissionDao permissionDao;
    @Resource
    private RoleDao roleDao;

    @Override
    public User getById(Integer id) {
        return userDao.queryById(id);
    }

    @Override
    public void register(User user) {
        checkParam(user);
        String pwd = user.getPwd();
        pwd = Md5Util.encode(pwd);
        user.setPwd(pwd);
        user.setCreateDate(new Date());
        user.setUpdateDate(new Date());
        user.setIsValid(1);
        AssertUtil.isTure(userDao.insert(user) != 1, "register failed!");
    }

    @Override
    public UserModel login(String userName, String pwd) {
        if (ValidateUtil.blankString(userName) || ValidateUtil.blankString(pwd)) {
            throw new ParamsExcetion("用户名或密码不能为空", 500);
        }
        User user = userDao.queryByUserName(userName);
        AssertUtil.isTure(user == null, "用户名或密码不正确!");
        AssertUtil.isTure(user.getIsValid()==0,"用户已注销");
        String password = Md5Util.encode(pwd);
        AssertUtil.isTure(!password.equals(user.getPwd()), "用户名或密码不正确");

        return buildUserInfo(user);
    }

    private UserModel buildUserInfo(User user) {
        UserModel userModel = new UserModel();
        userModel.setUserName(user.getUsername());
        userModel.setIdStr(user.getId().toString());
        List<Integer> roleIds = userRoleDao.queryRoleIdsByUserId(user.getId());
        if(!ValidateUtil.blankList(roleIds)){

                List<String> permissions = permissionDao.queryPermissionsByRoleIds(roleIds);
                if(!ValidateUtil.blankList(permissions)){
                    userModel.setPermissions(permissions);
                }

        }
        return userModel;
    }

    @Override
    public void updateUserPassword(Integer uerId, String oldPassword, String newPassword1, String newPassword2) {
        checkParam(uerId, oldPassword, newPassword1, newPassword2);
        String newPwd = Md5Util.encode(newPassword1);
        Date updateDate = new Date();
        userDao.updateUserPwd(newPwd, updateDate, uerId);
    }

    @Override
    public String queryUser(Integer id) {
        return userDao.queryUser(id);
    }

    @Override
    public Map<String, Object> queryUserByParams(UserQuery userQuery) {
        PageHelper.startPage(userQuery.getPage(),userQuery.getRows());
        List<User> users = userDao.queryForPage(userQuery);
        if(null!=users&&users.size()>0){
            for (User user : users) {
                String roleIdsStr=user.getRoleIdsStr();
                if(!ValidateUtil.blankString(roleIdsStr)){
                    String[] tempRoleIds = roleIdsStr.split(",");
                    Integer[] ids = toIntegerArray(tempRoleIds);
                    user.setRoleIds(CollectionUtils.arrayToList(ids));
                }
            }
        }
        PageInfo<User> pageInfo = new PageInfo<User>(users);
        Map<String,Object> map = new HashMap<>();
        map.put("total",pageInfo.getTotal());
        map.put("rows",pageInfo.getList());
        return map;
    }

    @Override
    public void saveUser(User user) {
        /**
         * 1.参数合法性校验
         *   用户名
         *   密码
         *   trueName
         * 2.用户名唯一校验
         * 3.设置额外字段值
         *     isValid
         *     createDate
         *     updateDate
         * 4.执行添加
         * 5.关联角色
         *     如果添加用户选择角色 执行用户角色记录添加
         *
         */
        checkUserParams(user.getUsername(),user.getMobile());

        User temp = userDao.queryByUserName(user.getUsername());
        AssertUtil.isTure(null!=temp, "用户名已存在");

        user.setIsValid(1);
        user.setCreateDate(new Date());
        user.setUpdateDate(new Date());
        user.setPwd(Md5Util.encode("123456"));

        AssertUtil.isTure(userDao.insert(user)<1, DmConstant.OP_FAILED_MSG);

        List<Integer> roleIds = user.getRoleIds();

        if(null!=roleIds&&roleIds.size()>0){
            /**
             * 关联角色
             */
            relationUserRoles(user.getId(),roleIds);
        }
    }

    private void checkUserParams(String username, String mobile) {
        AssertUtil.isTure(StringUtils.isBlank(username), "用户名称非空");
        AssertUtil.isTure(StringUtils.isBlank(mobile), "用户手机号码非空");
    }

    private void relationUserRoles(Integer userId, List<Integer> roleIds) {
        /**
         * 批量添加用户角色记录到t_user_role表
         */
        Integer total = userRoleDao.queryUserRolesByUserId(userId);

        if(total>0){
            /**
             * 执行删除操作
             *   根据userId 执行删除
             *
             */
            AssertUtil.isTure(userRoleDao.deleteUserRolesByUserId(userId)<1, DmConstant.OP_FAILED_MSG);
        }

        if(null!=roleIds&&roleIds.size()>0){
            List<UserRole> userRoles = new ArrayList<UserRole>();
            for(Integer roleId: roleIds){
                UserRole userRole = new UserRole();
                userRole.setUserid(userId);
                userRole.setRoleid(roleId);
                userRole.setCreatedate(new Date());
                userRole.setUpdatedate(new Date());
                userRoles.add(userRole);
            }

            AssertUtil.isTure(userRoleDao.insertBatch(userRoles)<total, DmConstant.OP_FAILED_MSG);

        }
    }

    @Override
    public void updateUser(User user) {
        /**
         * 1.参数合法性校验
         *    userName
         *    trueName
         *  2.用户名唯一
         *  3.额外字段值设置
         *      updateDate
         *  4.执行更新
         *  5.关联用户角色
         */

        checkUserParams(user.getUsername(),user.getMobile());

        User temp = userDao.queryByUserName(user.getUsername());
        AssertUtil.isTure(null!=temp&&temp.getId()!=user.getId(), "用户名已存在！");
        user.setUpdateDate(new Date());
        AssertUtil.isTure(userDao.update(user)<1, DmConstant.OP_FAILED_MSG);
        List<Integer> roleIds = user.getRoleIds();
        relationUserRoles(user.getId(), roleIds);
    }

    @Override
    public void deleteUser(Integer id) {
        AssertUtil.isTure(null==id||null==userDao.queryById(id), "待删除的记录不存在");
        int total = userRoleDao.queryUserRolesByUserId(id);
        if(total>0){
            AssertUtil.isTure(userRoleDao.deleteUserRolesByUserId(id)<total, DmConstant.OP_FAILED_MSG);
        }
        AssertUtil.isTure(userDao.delete(id)<1, DmConstant.OP_FAILED_MSG);
    }

    private void checkParam(Integer uerId, String oldPassword, String newPassword, String confirmPassword) {
        AssertUtil.isTure(ValidateUtil.nullOrZeroInteger(uerId), "用户名不能为空");
        String old = Md5Util.encode(oldPassword);
        AssertUtil.isTure(!userDao.queryById(uerId).getPwd().equals(old), "旧密码不正确！");
        AssertUtil.isTure(oldPassword.equals(newPassword), "新旧不可相同");
        AssertUtil.isTure(ValidateUtil.blankString(oldPassword), "旧密码不能为空");
        AssertUtil.isTure(ValidateUtil.blankString(newPassword), "新密码不能为空");
        AssertUtil.isTure(ValidateUtil.blankString(confirmPassword), "重复输入的新密码不能为空");
        AssertUtil.isTure(!newPassword.equals(confirmPassword), "两次密码不一致！");
    }

    private void checkParam(User user) {
        if (ValidateUtil.blankString(user.getUsername()) || ValidateUtil.blankString(user.getPwd()) || ValidateUtil.blankString(user.getMobile())) {
            throw new ParamsExcetion("name or pwd or mobile is needded", 300);
        }
        if (user.getPwd().length() > 6) {
            throw new ParamsExcetion("password should be 6 long", 500);
        }
        AssertUtil.isTure(userDao.queryByUserName(user.getUsername()) != null, "userName is existed");
        AssertUtil.isTure(userDao.queryByMobile(user.getMobile()) != null, "mobile has been registered");
    }

    /**
     * 将字符传输组转换成Inteter数组
     *
     * @param tempRoleIds
     * @return
     */
    private Integer[] toIntegerArray(String[] tempRoleIds) {
        Integer[] ids=null;
        if(null!=tempRoleIds&&tempRoleIds.length>0){
            ids= new Integer[tempRoleIds.length];
            for (int i=0;i<tempRoleIds.length;i++) {
                ids[i]=Integer.parseInt(tempRoleIds[i]);
            }
        }
        return ids;
    }
}
